Getting the ball rolling
Jul 5, 2025 - ⧖ 6 minFirst off, I'll point out that I'm not a professional IT Systems Administrator or anything that comes even relatively close. There are several layers to the problem I'm trying to solve with this site, and each one presented foreign challenges to me. The things you see me do in this post may be inefficient, and that's just because I'm learning my way through it. Enjoy the read, and copy at your own risk!
Infrastructure
In short, this site is hosted on the cheapest Linode "Nanode" that I could purchase, and Porkbun provides the domain. After getting the VPS setup with NixOS using this guide from Linode, I was off to the races.
Note
As of July 2025, the Linode guide mentions to use only 1280Mb
for the Installer
disk. The size of the minimal NixOS ISO is larger than that, so I set this disk to 2000Mb
and was able to get it to work. I emailed Linode support about this, and they promptly confirmed the same day that they would update the guide - a big thumbs up to their support team!
After getting the VPS setup, I grabbed the public facing IP address and set that in Porkbun as the target for the dumbscadaguy.com domain. It couldn't be much easier, especially for someone like me that had no exposure to this type of work before. Now that the "infrastructure" was setup, it was time to enter a more familiar wheelhouse - NixOS configuration.
Configuration
Placeholder for NixOS configuration link
As mentioned already, I chose to use NixOS for this system. I love the comfort of knowing I can use a configuration.nix
file and have the same setup reproducible somewhere else with very few variables undeclared to mess up a new deployment. However, I'll note that I'm not doing this initial setup with NixOS Flakes. This marvel of modern software engineering gives me rock-solid confidence that I can reproduce my setup anywhere else given an internet connection and a resolution to only configure applications within my *.nix
files. While this is the ideal end-goal, I'm trying to walk before I run here. The default NixOS installer doesn't implement flakes and I will burn that bridge in the future.
Web Server
Ok, time to dig into the nitty-gritty of the configuration.nix
goodness that makes this site possible. First, we have Caddy. I was able to get a webserver up and running for static files in my specified /var/www/dumbscadaguy
directory just by simply declaring this in my configuration.nix
file:
services.caddy = {
enable = true;
virtualHosts."dumbscadaguy.com" = {
extraConfig = ''
root * /var/www/dumbscadaguy
file_server
''
};
};
At this point, now I have anything that is "servable" in my /var/www/dumbscadaguy
directory available to the public internet. What a great deal - I quickly put a simple .html file out there so I could unimpress my wife. Bless her heart 🙂
Static Site Generator
To take things from black words on a white background up to an actual "website" with formatting and theming, I chose a markdown static site generator (SSG) called Marmite. I chose it simply because it has minimal configuration options and could be run via a single Rust binary. I had a couple of things to do for making this choice actually function for me. First, I needed to add the marmite
package to the environment.systemPackages
set in my configuration.nix
file. Easy enough, but how do I make sure it can automatically run and watch for file changes every time the sytem goes up? A systemd unit, of course!
I'm very green with systemd, so I did the bare-minimum to get this running. Here's what I came up with, and it worked on the first try:
systemd.services.marmite_dumbscadaguy = {
wantedBy = [ "multi-user.target" ];
description = "SSG for DSG site";
serviceConfig = {
Type = "simple";
User = "root";
ExecStart = ''${pkgs.marmite}/bin/marmite --watch --name dumbscadaguy.com --tagline "It's all just 1's and 0's!" --colorscheme gruvbox --toc true --enable-search true /srv/www/dumbscadaguy /var/www/dumbscadaguy''
};
};
As you can see, that really wasn't too bad for how much flexibility it gives! I just need to get files into the /srv/www/dumbscadaguy
directory, and they'll get a pretty HTML file generated in the /var/www/dumbscadaguy
directory that Caddy is serving. Simply elegant, and exactly what I wanted. I can configure some simple options right there on that CLI command, and not have to worry about some external non-Nix file to manage. I know there's more flexible and configurable SSG options out there, but this fits my current needs!
Source Control
To make it easier to create a content pipeline for myself, I chose to use git as the tool of choice. With a private Github repo setup, I used the native Nix package gh
to authenticate to Github on the server and some clients. The magic is really in how I set up periodic git pull
syncing on the server to get anything new displayed to the public internet.
Here's what I ended up doing, again using systemd. First we define the service that does the actual pull action using git:
systemd.services.git_pull_dumbscadaguy = {
description = "pull git repo changes";
path = with pkgs; [ git ];
serviceConfig = {
Type = "oneshot";
User = "aaron";
WorkingDirectory = "/srv/www/dumbscadaguy";
ExecStart = "${pkgs.git}/bin/git pull";
};
};
Next, there needs to be a periodic service that re-runs the git_pull_dumbscadaguy
service to pull updates:
systemd.timers.git_pull_dumbscadaguy = {
description = "Timer to pull git repo changes";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1m";
OnUnitActiveSec = "1m";
Unit = "git_pull_dumbscadaguy.service";
};
};
I was able to get the "git autosync" feature to work using the systemd units above. It was good to learn the simple cabilities of systemd, which up until now have been a scary barrier. I will be able to dig deeper sometime soon.
With that, I am up and running with a bit of confidence now. I'm pleasantly surprised with how things are coming along, and it gives me enthusiasm to continue working on this!